package com.biyu.monitormanage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.biyu.monitormanage.common.exception.BizException;
import com.biyu.monitormanage.common.utils.*;
import com.biyu.monitormanage.dao.MachineDao;
import com.biyu.monitormanage.dao.RealTimeDataDao;
import com.biyu.monitormanage.entity.MachineEntity;
import com.biyu.monitormanage.entity.RealTimeDataEntity;
import com.biyu.monitormanage.enums.MonitorStatusEnums;
import com.biyu.monitormanage.enums.PositionEnums;
import com.biyu.monitormanage.enums.WrongEnums;
import com.biyu.monitormanage.model.bo.MachineMonitorBo;
import com.biyu.monitormanage.model.dto.MonitorMapDto;
import com.biyu.monitormanage.service.MachineService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * 机器表
 * @author biyuing
 */
@Service("machineService")
public class MachineServiceImpl extends ServiceImpl<MachineDao, MachineEntity> implements MachineService {

    private final MachineDao machineDao;
    private final RealTimeDataDao realTimeDataDao;

    @Autowired
    public MachineServiceImpl(MachineDao machineDao, RealTimeDataDao realTimeDataDao) {
        this.machineDao = machineDao;
        this.realTimeDataDao = realTimeDataDao;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String machineName = (String) params.get("machineName");
        IPage<MachineEntity> page = this.page(
                new Query<MachineEntity>().getPage(params),
                new QueryWrapper<MachineEntity>()
                        .like(StringUtils.isNotBlank(machineName),"machine_name", machineName)
        );

        return new PageUtils(page);
    }

    @Override
    public List<MachineMonitorBo> queryMonitorAndApply(Map<String, Object> params) {
        String department = (String)params.get("department");
        String machineName = (String)params.get("machineName");
        String monitorParam = (String)params.get("monitorParam");
        // 1、先根据参数查机器
        List<MachineEntity> machineEntities = machineDao.selectByDepartmentOrName(department, machineName);
        return exchangeMachineMonitoringParamDtoList(machineEntities, monitorParam);
    }


    @Override
    public List<MachineMonitorBo> exchangeMachineMonitoringParamDtoList(List<MachineEntity> machineEntities, String monitorParam) {
        List<MachineMonitorBo> machineMonitorBoList = new ArrayList<>();
        machineEntities.stream().filter(Objects::nonNull).forEach(machineEntity -> {
            // 1、封装首页展示名称 部门+方位+机器名
            String machineName = MachineUtils.getMachineName(machineEntity);
            // 2、封装传入数据 key-value
            List<MachineMonitorBo> machineMonitorBos = getMachineMonitorBos(machineName,
                                                                            machineEntity.getMachineId(),
                                                                            monitorParam);
            machineMonitorBoList.addAll(machineMonitorBos);
        });
        return machineMonitorBoList;
    }

    @Override
    public List<MonitorMapDto> monitorMap(Map<String, Object> params) {
        // 0、新建一个list
        List<MonitorMapDto> list = new ArrayList<>();
        // 1、查询最新一条数据
        Map<String, Object> param = new HashMap<>();
        String monitorParam = (String) params.get("monitorParam");
        if (StringUtils.isBlank(monitorParam)) {
            monitorParam = "temperature";
        }
        param.put(monitorParam, 4);
        RealTimeDataEntity realTimeDataEntity = realTimeDataDao.selectNew(param);
        if (Objects.isNull(realTimeDataEntity)) {
            throw new BizException(WrongEnums.RESULT_NULL.getCode(), "查询最新数据异常");
        }
        // 2、获得最新数据的机器id
        String machineId = realTimeDataEntity.getMachineId();
        QueryWrapper<MachineEntity> wrapper = new QueryWrapper<>();
        // 3、查机器实体
        MachineEntity machineEntity = machineDao.selectOne(wrapper.eq("machine_id", machineId));
        if (Objects.isNull(machineEntity)) {
            throw new BizException(WrongEnums.RESULT_NULL.getCode(), "查询最新数据的机器异常");
        }
        // 4、得到区域名称
        String name = machineEntity.getRegion();
        // 5、得到参数数据
        String value = getRealParamVal((String) params.get("monitorParam"), realTimeDataEntity);
        MonitorMapDto build = MonitorMapDto.builder().name(name).value(value).build();
        list.add(build);
        ListUtils.addParams(list);
        return list;
    }

    private String getRealParamVal(String param, RealTimeDataEntity realTimeDataEntity) {
        if (Objects.equals(param, "temperature")){
            return realTimeDataEntity.getTemperature().toString() + "℃";
        }
        if (Objects.equals(param, "humidity")) {
            return realTimeDataEntity.getHumidity().toString() + "%";
        }
        if (Objects.equals(param, "smokeSensor")) {
            return MonitorStatusEnums.getDesc(realTimeDataEntity.getSmokeSensor());
        }
        if (Objects.equals(param, "waterLeakage")) {
            return MonitorStatusEnums.getDesc(realTimeDataEntity.getWaterLeakage());
        }
        if (Objects.equals(param, "infraRed")) {
            return MonitorStatusEnums.getDesc(realTimeDataEntity.getInfraRed());
        }
        return realTimeDataEntity.getTemperature().toString() + "℃";
    }

    /**
     * 如果温度、湿度、漏水等参数不为空 就添加到列表中
     * @param machineMonitorName 机器实体名称
     * @param machineId 机器实体id
     * @return 参数列表
     */
    private List<MachineMonitorBo> getMachineMonitorBos(String machineMonitorName, String machineId, String monitorParam) {
        // 1、查询最早温湿度记录
        Map<String, Object> params = new HashMap<>();
        MapUtils.savaParams(params, monitorParam);
        params.put("machineId", machineId);
        RealTimeDataEntity realTimeDataEntity = realTimeDataDao.selectRealData(params);

        // 2、封装到Bo对象列表中
        List<MachineMonitorBo> machineMonitorBos = new ArrayList<>();
        MachineMonitorBo.addMachineMonitorBo(machineMonitorBos, realTimeDataEntity, machineMonitorName);

        // 3、返回封装的列表
        return machineMonitorBos;
    }
}